package com.apes.fn.business.carAccident.service;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.apes.crm.business.model.InsuranceCompany;
import com.apes.crm.business.repository.InsuranceCompanyRepository;
import com.apes.fn.business.carAccident.modle.CarAccident;
import com.apes.fn.business.carAccident.modle.CarEvaluation;
import com.apes.fn.business.carAccident.modle.ClaimWorkOrder;
import com.apes.fn.business.carAccident.modle.PickCarTypeAccident;
import com.apes.fn.business.carAccident.repository.CarAccidentRepository;
import com.apes.fn.business.carAccident.repository.ClaimWorkOrderRepository;
import com.apes.fn.business.fixedLoss.modle.LossQuotation;
import com.apes.fn.business.fixedLoss.modle.LossQuotationItem;
import com.apes.fn.business.fixedLoss.modle.LossQuotationPlan;
import com.apes.fn.business.fixedLoss.repository.LossQuotationRepository;
import com.apes.fn.business.fixedLoss.service.FixedLossToForeign;
import com.apes.fn.business.fixedLoss.service.LossQuotationService;
import com.apes.fn.business.insurance.modle.InsuranceOrder;
import com.apes.fn.business.insurance.modle.PolicyInformation;
import com.apes.fn.business.insurance.repository.InsuranceOrderRepository;
import com.apes.fn.business.insurance.repository.PolicyInformationRepository;
import com.apes.fn.crm.customerExpand.FnCustomerExpand;
import com.apes.fn.crm.customerExpand.FnCustomerExpandRepository;
import com.apes.fn.crm.customerExpand.PickUpTypeF;
import com.apes.fn.scm.insuranceRules.InsuranceRule;
import com.apes.fn.scm.insuranceRules.InsuranceRuleService;
import com.apes.fn.scm.retailOrder.model.RetailOrder;
import com.apes.fn.scm.retailOrder.repository.RetailOrderRepository;
import com.apes.fn.server.pickUpCar.model.PickUpCar;
import com.apes.fn.server.pickUpCar.repository.PickUpCarRepository;
import com.apes.fn.server.pickUpCar.service.PickUpCarService;
import com.apes.fn.server.productRequire.ProductRequire;
import com.apes.fn.server.servicePlan.service.ServicePlanceService;
import com.apes.framework.api.DomainService;
import com.apes.framework.api.SpringManager;
import com.apes.framework.jpa.logger.ApesLoggerService;
import com.apes.framework.jpa.spec.JpaDsl;
import com.apes.framework.plugin.esb.api.SimpleRequest;
import com.apes.framework.plugin.mq.MQUtil;
import com.apes.framework.plugin.mq.annotation.Consumer;
import com.apes.framework.plugin.outbox.OutboxEventService;
import com.apes.framework.plugin.outbox.OutboxPayloadWrapper;
import com.apes.framework.plugin.outbox.annotation.OutboxSubscriber;
import com.apes.framework.plugin.soe.metadata.BusinessAttributeValue;
import com.apes.framework.plugin.soe.store.database.repository.BusinessAttributeValueRepository;
import com.apes.framework.util.DateUtil;
import com.apes.framework.util.DistributedLock;
import com.apes.framework.util.MapUtil;
import com.apes.hr.base.model.Employee;
import com.apes.hr.base.repository.EmployeeRepository;
import com.apes.pi.service.PiManager;
import com.apes.scm.masterdata.enumeration.model.Enumeration;
import com.apes.scm.masterdata.enumeration.repository.EnumerationRepository;
import com.apes.scm.masterdata.frame.model.Dept;
import com.apes.scm.masterdata.frame.model.Store;
import com.apes.scm.masterdata.frame.repository.DeptRepository;
import com.apes.scm.masterdata.frame.repository.StoreRepository;
import com.apes.scm.masterdata.party.model.PartyRole;
import com.apes.scm.masterdata.party.repository.PartyRoleRepository;
import com.apes.scm.rbac.model.User;
import com.apes.scm.rbac.repository.UserRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Sort;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import java.util.*;
import java.util.stream.Collectors;

import static java.util.Objects.isNull;

/**
 * @ClassName : CarAccidentService
 * @Description : 车险报案单业务层
 * @Author : WSJ
 * @Date: 2020-03-07 14:51
 */
@Service("carAccidentService")
public class CarAccidentService extends DomainService {
    @Autowired
    private CarAccidentRepository carAccidentRepository;

    @Autowired
    private PiManager piManager;

    @Autowired
    private InsuranceOrderRepository insuranceOrderRepository;

    @Autowired
    private StoreRepository storeRepository;

    @Autowired
    private DistributedLock distributedLock;

    public CarAccident save(SimpleRequest request) {
        //判断是否存在有效的相同的报案单号和车牌的车险报案单号
        CarAccident carAccident = updateOrInsertCustomerExpand(request);
        if (carAccident.getSourceFrom() == null) {
            carAccident.setSourceFrom("手动建单");
        }

        checkExistsCarAccident(carAccident);
        // 检查报案号是否符合保险公司的报案号标准
        checkReportNumberStandard(carAccident);
        //检查门店得定损额度是否足够
        checkStoreQuota(carAccident);
        if (carAccident.getDept() == null ) {
            carAccident.setState("backStage");
        }else {
            setPeopleData(carAccident,request);
            carAccident.setState("store");
        }
        //判断责任
        checkVehicleDuty(carAccident);
        List<CarAccident> carAccidents = getCarAccidents(carAccident.getReportNumber(), carAccident.getCarNumber(),null);
        if (!carAccidents.isEmpty()){
            // 下面设置状态是：检查是否存在相同报案号和车牌的车险报案单号，如果存在之前有的单据就设置为 转后台，现在都是门店做单，放开控制
//            carAccident.setState("backStage");
            carAccident.setHistoryOrder(carAccidents.get(0).getId());
        }
        carAccident.setBusinessTypeName("车险报案单");
        //界面新增会自动new CarEvaluation()
        if (Objects.isNull(carAccident.getCarEvaluations().getClaimType())) {
            carAccident.setCarEvaluations(null);
        }
        checkDamagePoint(carAccident);
        checkInStoreState(carAccident);
        carAccident = carAccidentRepository.saveAndFlush(carAccident);
        try {
            if (carAccident.getCaseType().getId().equals("001492")&&carAccident.getDept() != null)this.invoke("fn.carAccident.claimWorkOrder",MapUtil.mapped(carAccident));
        }catch (Exception e){
            if (!e.getMessage().contains("定损工单")){
                throw new RuntimeException(e.getMessage());
            }
        }
//        carAccidentSaveToApp(getAppSaveParam(carAccident));
        return  carAccident;
    }

    /**
     * 判断保单号是否到期
     * 未到期则修改案件类型为:车险会员报案
     * @param carAccident
     */
    private void checkVehicleDuty(CarAccident carAccident) {
        if (!"4".equals(carAccident.getVehicleDuty().getCode()) && Objects.isNull(carAccident.getCaseType())) {
            InsuranceOrder insuranceOrder = insuranceOrderRepository.findAll(JpaDsl.toCriteria(
                    "licensePlate", "EQ", carAccident.getCarNumber(),
                    "stateName", "EQ", "生成保单"
            ), new Sort(Sort.Direction.DESC, "createDate"))
                    .stream().findFirst().orElse(null);
            if (insuranceOrder==null) return;
            List<PolicyInformation> policyInformationList = SpringManager.getBean(PolicyInformationRepository.class).findAll(JpaDsl.toCriteria(
                    "insuranceType", "EQ", "0",
                    "startDate", "LT", new Date(),
                    "endDate", "GT", new Date(),
                    "APPOrder","EQ",insuranceOrder.getAPPOrder()
            ));
            if (policyInformationList.isEmpty())return;
            Enumeration enumeration = SpringManager.getBean(EnumerationRepository.class).findOne("001491");//车险会员报案
            carAccident.setCaseType(enumeration);
            carAccident.setAPPOrder(insuranceOrder.getAPPOrder());
        }
    }


    @OutboxSubscriber(name = "推送报案单给app")
    public void subscribeCarAccident(CarAccident carAccident) {
        JSONObject payloadJson = new JSONObject(getAppSaveParam(carAccident));

        JSONObject response = JSONObject.parseObject(
                this.invoke("pi.app.ext", MapUtil.mapper(
                        "headers",MapUtil.mapper("method","v1/tracking/yyerp-tracking-report/add-report","action","post"),
                        "body",payloadJson)
                )
        );
        try {
            if(!response.getBoolean("success")){
                throw new RuntimeException("AppError:" + response.toJSONString());
            }
        }catch (Exception e){
            throw new RuntimeException("AppError:" + response.toJSONString());
        }

    }
    public void carAccidentSaveToApp(Map carAccident){
        OutboxPayloadWrapper wrapper = new OutboxPayloadWrapper();
        wrapper.setSubscriber("carAccident.loss.saveToApp");
        wrapper.setAggregateId("CarAccident:" + carAccident.get("orderNumber"));
        try {
            wrapper.setPayload(JSON.toJSONString(carAccident));
        } catch (Exception e) {
            throw new RuntimeException(e.getMessage());
        }
        SpringManager.getBean(OutboxEventService.class).sendSaveEvent(wrapper);
    }
    public void checkInStoreState(CarAccident carAccident){
        if(!carAccident.getState().equals("store"))return;
        List<PickUpCar> approve = SpringManager.getBean(PickUpCarRepository.class).findByLicenseNumberAndDeptAndState(carAccident.getCarNumber(), carAccident.getDept(), "approve");
        if (approve.isEmpty())return;
        PickUpCar pickUpCar = approve.get(0);
        carAccident.setState("inStore");
        carAccident.setPickCarTime(pickUpCar.getCreateDate());
    }
    /**
     * 通知app
     *
     * @param
     */
    @OutboxSubscriber(id="carAccident.loss.saveToApp", name="推送报案单给app")
    public void carAccidentSaveToApp(OutboxPayloadWrapper outboxPayloadWrapper){
        JSONObject payloadJson = JSONObject.parseObject(outboxPayloadWrapper.getPayload());

        JSONObject response = JSONObject.parseObject(
                this.invoke("pi.app.ext", MapUtil.mapper(
                        "headers",MapUtil.mapper("method","v1/tracking/yyerp-tracking-report/add-report","action","post"),
                        "body",payloadJson)
                )
        );
        try {
            if(!response.getBoolean("success")){
                throw new RuntimeException("AppError:" + response.toJSONString());
            }
        }catch (Exception e){
            throw new RuntimeException("AppError:" + response.toJSONString());
        }

    }

    private Dept checkCarInsuranceDept(SimpleRequest request){
        JSONObject jo = request.getJO();
        String carLicense = jo.getString("carLicense");
        InsuranceOrder insuranceOrder = insuranceOrderRepository.findAll(JpaDsl.toCriteria("licensePlate", "EQ", carLicense, "stateName", "EQ", "生成保单"), new Sort(Sort.Direction.DESC, "createDate"))
                .stream().findFirst().orElse(null);
        if (insuranceOrder==null) return null;
        return insuranceOrder.getDept();

    }
    private FnCustomerExpand checkCustomerInfo(SimpleRequest request){
        JSONObject jo = request.getJO();
        String carLicense = jo.getString("carLicense");
        FnCustomerExpand fnCustomerExpand = SpringManager.getBean(FnCustomerExpandRepository.class)
                .findAll(
                        JpaDsl.toCriteria("carLicense", "EQ", carLicense),
                        new Sort(Sort.Direction.DESC, "createDate")
                )
                .stream().findFirst().orElse(null);
        if (fnCustomerExpand==null) return null;
        return fnCustomerExpand;

    }

    private Map carAccidentSaveToAppTest(SimpleRequest request){
        JSONObject response = new JSONObject();
        JSONObject jo = request.getJO();
        CarAccident old = carAccidentRepository.findOne(jo.getString("id"));
//        JSONObject jsonObject = new JSONObject(MapUtil.mapped(old, "carEvaluations", "dept"));
//        jsonObject.put("repealRemarks","1");
//        BeanUtils.copyProperties(MapUtil.getO(jsonObject,CarAccident.class),old,"carEvaluations");
//        CarAccident carAccident = carAccidentRepository.saveAndFlush(old);


//        JSONObject jo = request.getJO();
//        CarAccident carAccident = carAccidentRepository.findOne(jo.getString("id"));
//
//
//        JSONObject response = JSONObject.parseObject(
//                this.invoke("pi.app.ext", MapUtil.mapper(
//                        "headers",MapUtil.mapper("method","v1/tracking/yyerp-tracking-report/add-report","action","post"),
//                        "body",getAppSaveParam(carAccident))
//                )
//        );
        return MapUtil.mapped(old,"carEvaluations","customerExpand","typeAccidents");
    }

    public Map<String,Object> getAppSaveParam(CarAccident carAccident){
        CarEvaluation carEvaluations = carAccident.getCarEvaluations()==null?new CarEvaluation():carAccident.getCarEvaluations();
        return MapUtil.mapper("reportNumber",carAccident.getReportNumber(),"carLicense",carAccident.getCarNumber(),
                "orderNumber",carAccident.getId(),"reportPerson",carAccident.getReportPerson(),
                "source",carAccident.getSourceFrom(),"type",carAccident.getBusinessTypeName(),
                "status",carAccident.getState(),"singlePerson",carAccident.getCreator(),
                "insuranceCompany",carAccident.getInsuranceCompany().getName(),
                "appearDate",carAccident.getReportDate()!=null?DateUtil.format(carAccident.getCarAccidentDate(),DateUtil.SHOW_DATE_FORMAT):null,
                "reportDate",carAccident.getReportDate()!=null?DateUtil.format(carAccident.getReportDate(),DateUtil.SHOW_DATE_FORMAT):null,
                "singleDate",carAccident.getCreateDate()!=null?DateUtil.format(carAccident.getCreateDate(),DateUtil.SHOW_DATE_FORMAT):null,
                "shopDoorDate",carAccident.getToStoreDate()!=null?DateUtil.format(carAccident.getToStoreDate(),DateUtil.SHOW_DATE_FORMAT):null,
                "selfResponsibility",carAccident.getVehicleDuty()!=null?carAccident.getVehicleDuty().getName():null,
                "injuryNumber",Optional.ofNullable(carAccident.getInjured()).orElse(0)+Optional.ofNullable(carAccident.getDie()).orElse(0),
                "woundingNumber",carAccident.getInjured(),
                "storeName",carAccident.getDept()!=null?carAccident.getDept().getName():null,
                "storeCode",carAccident.getDept()!=null?carAccident.getDept().getId():null,
                "carModelName",carAccident.getCustomerExpand()!=null?carAccident.getCustomerExpand().getCarModelLabel():null,
                "inDangerPlace",carAccident.getCarAccidentPlace(),
                "feeWayOne",carEvaluations.getFixedLossType()!=null?carEvaluations.getFixedLossType().getName():null,
                "repairPlace",carEvaluations.getRepairPlace()!=null?carEvaluations.getRepairPlace().getName():null,
                "partFee",carEvaluations.getGetCarUid()!=null?carEvaluations.getGetCarUid().getName():null,
                "assistFee",carEvaluations.getAssistUid()!=null?carEvaluations.getAssistUid().getName():null,
                "appraisalDate",carEvaluations.getCreateDate()!=null?DateUtil.format(carEvaluations.getCreateDate(),DateUtil.SHOW_DATE_FORMAT):null,
                "trackingTime",carAccident.getTrackDate()!=null?DateUtil.format(carAccident.getTrackDate(),DateUtil.SHOW_DATE_FORMAT):null,
                "makingDepartment",carAccident.getDept()!=null?carAccident.getDept().getId():null,
                "timestamp",new Date(),
                "orderStatus",carAccident.getState(),
                "orderStatus",carAccident.getStateName(carAccident.getState()),
                "afterGetDanger",carAccident.getCarAccidentDescribe(),
                "storeFollowEmployeeCode",carAccident.getStaff()!=null?carAccident.getStaff().getId():null,
                "storeFollowEmployeeName",carAccident.getStaff()!=null?carAccident.getStaff().getName():null,
                "accidentType",carAccident.getAccidentType()!=null?carAccident.getAccidentType().getName():null,
                "trackingEmployeeName",carAccident.getBusinessStaff()!=null?carAccident.getBusinessStaff().getName():null,
                "trackingEmployeeCode",carAccident.getBusinessStaff()!=null?carAccident.getBusinessStaff().getId():null,
                "reporterMobile",carAccident.getPhoneNumber(),"insuredPerson",carAccident.getReportPerson(),
                "from",carAccident.getCaseType().getId(),"reportType",carAccident.getDangerType().getName()
                //"woundingNumber","","pickCarTime","","trailerMark","","blacklistPerson","","backlistDate","""pickCarDate":"转接车日期",\

        );
    }


    /**
     *
     * @param request
     */
    private CarAccident updataForApp(SimpleRequest request){
        JSONObject jo = request.getJO();
        CarAccident carAccident = carAccidentRepository.findOne(jo.getString("id"));
        if (carAccident==null)throw new RuntimeException("不存在的报案单号");
        if (carAccident.getState().equals("fixedLoss"))throw new RuntimeException("当前报案单为转定损状态,无法更新");
        if (carAccident.getState().equals("repeal"))throw new RuntimeException("当前报案单为终止状态,无法更新");
        PartyRoleRepository partyRoleRepository = SpringManager.getBean(PartyRoleRepository.class);
        carAccident.setStaff(jo.get("staff")!=null?partyRoleRepository.findOne(jo.getString("staff")):null);
        carAccident.setBusinessStaff(jo.get("businessStaff")!=null?partyRoleRepository.findOne(jo.getString("businessStaff")):null);
//        carAccident.setCarNumber(jo.getString("carNumber"));
//        carAccident.setInsuranceCompany(SpringManager.getBean(InsuranceCompanyRepository.class).findOne("insuranceCompany"));
//        carAccident.setCaseType(jo.getString("caseType")!=null?enumerationRepository.findOne(jo.getString("caseType")):null);
//        carAccident.setSourceFrom(jo.getString("sourceFrom"));
//        carAccident.setReportNumber(jo.getString("reportNumber"));
//        carAccident.setReportPerson(jo.getString("reportPerson"));
//        carAccident.setPhoneNumber(jo.getString("phoneNumber"));
//        carAccident.setThirdPartyPhone(jo.getString("thirdPartyPhone"));
//        carAccident.setCarAccidentPlace(jo.getString("carAccidentPlace"));
//        carAccident.setCarAccidentDate(jo.getDate("carAccidentDate"));
//        carAccident.setReportDate(jo.getDate("reportDate"));
        if(jo.get("trackDate")!=null)carAccident.setTrackDate(jo.getDate("trackDate"));
//        carAccident.setCarAccidentDescribe(jo.getString("carAccidentDescribe"));
//        carAccident.setAccidentType(businessAttributeValueRepository.findOne(jo.getString("accidentType")));
//        carAccident.setDangerType(businessAttributeValueRepository.findOne(jo.getString("dangerType")));
//        carAccident.setVehicleDuty(businessAttributeValueRepository.findOne(jo.getString("vehicleDuty")));
//        carAccident.setInjured(jo.getIntValue("injured"));
//        carAccident.setDie(jo.getIntValue("die"));
//        carAccident.setWaterloggedCar(enumerationRepository.findOne(jo.getString("waterloggedCar")));
        if(jo.get("repealRemarks")!=null)carAccident.setRepealRemarks(jo.getString("repealRemarks"));
        carAccident.setDept(jo.getString("dept")!=null?SpringManager.getBean(DeptRepository.class).findOne(jo.getString("dept")):null);
        carAccident.setState(jo.getString("state"));
        if(jo.get("toStoreUid")!=null)carAccident.setToStoreUid(partyRoleRepository.findOne(jo.getString("toStoreUid")));
        if(jo.get("toStoreDate")!=null)carAccident.setToStoreDate(jo.getDate("toStoreDate"));
        if(jo.get("backStageUid")!=null)carAccident.setBackStageUid(partyRoleRepository.findOne(jo.getString("backStageUid")));
        if(jo.get("backStageDate")!=null)carAccident.setBackStageDate(jo.getDate("backStageDate"));
        if(jo.get("repealUid")!=null)carAccident.setRepealUid(partyRoleRepository.findOne(jo.getString("repealUid")));
        if(jo.get("repealDate")!=null)carAccident.setRepealDate(jo.getDate("repealDate"));
        return carAccidentRepository.saveAndFlush(carAccident);

    }

//    /**
//     *
//     * @param request
//     */
//    private CarAccident updataForApp(SimpleRequest request){
//        CarAccident newCarAccident = MapUtil.getO(request.getMap(), CarAccident.class);
//        CarAccident oldCarAccident = carAccidentRepository.findOne(newCarAccident.getId());
//        BeanUtils.copyProperties(newCarAccident,oldCarAccident,"carEvaluations","customerExpand","typeAccidents");
//        return  carAccidentRepository.saveAndFlush(oldCarAccident);
//    }

    private void setPeopleData (CarAccident carAccident,SimpleRequest request) {
        //门店跟进人如果为空时,则默认为该门店店长
        if (Objects.isNull(carAccident.getStaff())) {
            setFollowUpPeople(carAccident);
        }
//        if (Objects.isNull(carAccident.getBusinessStaff())) {
//            carAccident.setBusinessStaff(getPerson(request));
//        }
    }

    /**
     * 同步老框架
     * @param outboxPayloadWrapper 事务发件箱
     */
    @OutboxSubscriber(id="local:CarAccident.synOldSystem", name="同步给老框架")
    private void synOldSystem(OutboxPayloadWrapper outboxPayloadWrapper) {
        JSONObject object = JSONObject.parseObject(outboxPayloadWrapper.getPayload());
        if (!object.containsKey("id")) {
            throw new RuntimeException("车险报案单号不能为空!!!");
        }
        CarAccident carAccident = carAccidentRepository.findOne(object.getString("id"));
        //把部门的编码转换为老框架编码
        Map map = changeOldSystemCode(carAccident);
        MQUtil.publish("ipmBusinessAffairsService.insertCXBAD", "同步车险保单到老框架", map);
        CarEvaluation carEvaluation = carAccident.getCarEvaluations();

        carAccidentRepository.saveAndFlush(carAccident);
    }

    /**
     * 转换老框架编码
     * @param carAccident
     */
    private Map changeOldSystemCode(CarAccident carAccident) {
        FnCustomerExpand expand = carAccident.getCustomerExpand();
        Map map = MapUtil.mapped(carAccident);
        assert map != null;
        if(Objects.nonNull(carAccident.getDept())){
            String origin = carAccident.getDept().getOrigin() == null ? carAccident.getDept().getId():carAccident.getDept().getOrigin();
            JSONObject dept = new  JSONObject ((Map<String,Object>)map.get("dept"));
            dept.put("id", origin);
            map.put("dept", dept);
        }
        CarEvaluation evaluation = carAccident.getCarEvaluations();
        if (Objects.nonNull(evaluation) && Objects.nonNull(evaluation.getBase())) {
            String baseOrigin = evaluation.getBase().getOrigin()  == null ? evaluation.getBase().getId() :evaluation.getBase().getOrigin();
            JSONObject carEvaluation = new  JSONObject ((Map<String,Object>)map.get("carEvaluations"));
            JSONObject base = carEvaluation.getJSONObject("base");
            base.put("id",baseOrigin);
        }
        //获取车辆相关信息
        map.put("vin", expand.getVin());
        map.put("jeKunModelCode", expand.getJekunModelCode());
        map.put("carModelLabel", expand.getCarModelLabel());
        return map;
    }

    public CarAccident update(SimpleRequest request) {
        checkData(request);
        CarAccident carAccident = request.getO(CarAccident.class);
        checkDamagePoint(carAccident);

        if (Objects.nonNull(carAccident.getDept())) {
            FnCustomerExpand customerExpand = getFnCustomerExpand(carAccident, carAccident.getCarNumber());
            if (Objects.nonNull(customerExpand)) {
                handleCustomerExpand(carAccident, carAccident.getCarNumber(), customerExpand);
            }
        }
        //检查门店得定损额度是否足够
        if (Objects.nonNull(carAccident.getDept()) && Objects.equals("backStage",carAccident.getState()) ) {
            setPeopleData(carAccident,request);
            carAccident.setState("store");
            try {
                if (carAccident.getCaseType().getId().equals("001492")&&carAccident.getDept() != null)this.invoke("fn.carAccident.claimWorkOrder",MapUtil.mapped(carAccident));
            }catch (Exception e){
                if (!e.getMessage().contains("定损工单")){
                    throw new RuntimeException(e.getMessage());
                }
            }
        }
        checkVehicleDuty(carAccident);
        checkStoreQuota(carAccident);
        if (Objects.isNull(carAccident.getCarEvaluations().getClaimType())) {
            carAccident.setCarEvaluations(null);
        }
        checkInStoreState(carAccident);
        carAccident = carAccidentRepository.saveAndFlush(carAccident);
        JSONObject object = new JSONObject();
        object.put("id", carAccident.getId());
//        SpringManager.getBean(OutboxSubscriberService.class).commonSendRequest("local:CarAccident.synOldSystem","Accident" + carAccident.getId(),object);
        return  carAccident;
    }

    /**
     * 异步同步报案单
     * @param request
     * @return
     */
    @Consumer(topic = "ipmBusinessAffairsService.insertCXBAD",backup = false)
    public void synCarAccident(SimpleRequest request) {
        try {
            // MapUtil.mapper(carAccident);
            JSONObject resultObj = piManager.synErp("ipmBusinessAffairsService.insertCXBAD", request.getMap());
            if (!resultObj.getBoolean("success")) {
                throw new RuntimeException(resultObj.getString("msg"));
            }
        } catch (Exception e) {
            System.out.println(e);
        }
    }
    /**
     * 检查是否存在未完成的车险报案单号
     * @param carAccident
     * @return
     */
    public void  checkExistsCarAccident(CarAccident carAccident) {
//        List<CarAccident> list = carAccidentRepository.findAll(
//                JpaDsl.toCriteriaByEq("carNumber",carAccident.getCarNumber(),
//                                    "reportNumber",carAccident.getReportNumber()) )
//                .stream().filter(
//                        item -> {
//                            return !"repeal".equals(item.getState());
//                        }
//                ).collect(Collectors.toList());
//
//        if (list.size() >0) {
//            throw new RuntimeException("该车牌该报案单号已经存在车险报案单,请勿重复创建!!!");
//        }
        //判断定损评估信息是否填写
        if (carAccident.isHelpReported()){
            if (isNull(carAccident.getCarEvaluations())) {
                throw new RuntimeException("评估信息未填写完成请补全!!!");
            }else {
                //控制 基地代报案的车险报案单只能选择转基地定损
                if (isNull(carAccident.getCarEvaluations().getBase())) {
                    throw new RuntimeException("基地代报案的车险报案单只能选择转基地定损!!!");
                }
            }
        }
    }
    /**
     * 终止车险报案单,同时终止相关定损报价单
     * @param request
     * @return
     * @throws Exception
     */
    public CarAccident repeal (SimpleRequest request) throws RuntimeException {
        checkData(request);
        //查询是否存在已生成服务单,要货单的 定损报价的单, 有则不能终止
        String carAccidentId = request.get("id");
        List<ProductRequire> list = carAccidentRepository.findProductRequireForID(carAccidentId);
        if (list.size() >0) throw new RuntimeException("该车险报案单相应的定损报价单已生成要货单，无法终止!!!");
        List<LossQuotationItem> lossQuotationItems = carAccidentRepository.findLossQuotationItemForID(carAccidentId);
        if (lossQuotationItems.size() >0) throw new RuntimeException("该车险报案单相应的定损报价单已经转修车,若要终止, 请先终止服务单!!!!");
        CarAccident carAccident = request.getO(CarAccident.class);
        if (carAccident.getRepealRemarks() == null) throw new RuntimeException("终止原因必须填写！");
        carAccident.setRepealUid(getPerson(request));//设置人员
        carAccident.setRepealDate(new Date());
        carAccident.setState("repeal");
        if (Objects.isNull(carAccident.getCarEvaluations().getClaimType())) {
            carAccident.setCarEvaluations(null);
        }
        carAccidentRepository.saveAndFlush(carAccident);
        // 终止 定损报价单
        List<LossQuotation> lossQuotations = carAccidentRepository.findLossQuotationForID(carAccidentId);
        if (lossQuotations.size() > 0) {
            lossQuotations.stream().forEach(
                    item -> {
                        item.setRepealUid(getPerson(request));//设置人员
                        item.setRepealDate(new Date());
                        item.setState("repeal");
                        SpringManager.getBean(LossQuotationRepository.class).saveAndFlush(item);
                    }
            );
        }
        PartyRole person = (PartyRole) getPerson(request);
        User user =SpringManager.getBean(UserRepository.class).findAll(JpaDsl.toCriteriaByEq("person.id",person.getId())).stream().findFirst().orElse(null);

        //创建日志
            sendSynEvent("event:ir.logger.create", mapper(
                    "businessType","CarAccident",
                    "businessKey", carAccident.getId(),
                    "operate", "终止",
                    "workPostName", null,
                    "remark", carAccident.getRepealRemarks(),
                    "oaFlag", false,
                    "operator_id",user == null ? null : user.getId()));
        //调用回传老框架报案单状态
        SpringManager.getBean(FixedLossToForeign.class).updateStateForCarAccident(carAccident);
        return carAccident;
    }

    /**
     * 功能：转门店
     *
     * @param request
     * @return
     */
    public CarAccident toStore(SimpleRequest request) {
        checkData(request);
        CarAccident carAccident = request.getO(CarAccident.class);
        if (Objects.isNull(carAccident.getDept())) {
            throw new RuntimeException("转门店操作,门店不能为空!!!");
        }
        //门店跟进人如果为空时,则默认为该门店店长
        if (Objects.isNull(carAccident.getStaff())) {
            setFollowUpPeople(carAccident);
        }
        if (Objects.isNull(carAccident.getBusinessStaff())) {
            carAccident.setBusinessStaff(getPerson(request));
        }
        carAccident.setState("store");
        carAccident.setToStoreUid(getPerson(request));
        carAccident.setToStoreDate(new Date());
        if (Objects.isNull(carAccident.getCarEvaluations().getClaimType())) {
            carAccident.setCarEvaluations(null);
        }
        checkInStoreState(carAccident);
        carAccident = carAccidentRepository.saveAndFlush(carAccident);
        //转门店 如果是代勘到店自动转工单
        if (Objects.equals(carAccident.getCaseType().getDescription(), "代勘到店")) {
            invoke("fn.carAccident.claimWorkOrder", MapUtil.mapped(carAccident));
        }
        return carAccident;
    }

    private void setFollowUpPeople (CarAccident carAccident) {
        Dept dept = carAccident.getDept();
        List<Employee>  employees = SpringManager.getBean(EmployeeRepository.class)
                .findAll(JpaDsl.toCriteriaByEq("workBranch", dept.getBranch(), "post.id", "0000016","employeeState.id","000088","quitState",null));
        if (employees.size()  == 0 ) {
            employees = SpringManager.getBean(EmployeeRepository.class)
                    .findAll(JpaDsl.toCriteriaByEq("workBranch", dept.getBranch(), "post.id", "0000752","employeeState.id","000088","quitState",null));
        }
        if (employees.size() == 0) {
            throw new RuntimeException("未找到该门店对应的店长,请手动选择门店跟进人!!!");
        }
        Employee employee = employees.stream().findFirst().orElse(new Employee());
        String origin = employee.getOrigin();
        PartyRole staff = SpringManager.getBean(PartyRoleRepository.class).findOne(origin);
        carAccident.setStaff(staff);
    }


    /**
     * 功能：转后台
     *
     * @param request
     * @return
     */
    public CarAccident toBlackStage(SimpleRequest request) {
        checkData(request);
        CarAccident carAccident = request.getO(CarAccident.class);
        carAccident.setState("backStage");
        carAccident.setBackStageUid(getPerson(request));
        carAccident.setBackStageDate(new Date());
        if (Objects.isNull(carAccident.getCarEvaluations().getClaimType())) {
            carAccident.setCarEvaluations(null);
        }
        carAccident = carAccidentRepository.saveAndFlush(carAccident);
        return  carAccident;
    }

    /**
     * 功能：基地代报案OA审批
     *
     */
    public CarAccident endOAAndApprove(SimpleRequest request) {
        CarAccident carAccident = request.getO(CarAccident.class);
        carAccident.setState("baseReported");
        carAccident = carAccidentRepository.saveAndFlush(carAccident);
        return  carAccident;
    }

    /**
     * 功能：
     * 转基地报案
     * @param request
     * @return
     */
    public CarAccident transferBase(SimpleRequest request) {
        CarAccident carAccident = request.getO(CarAccident.class);
        carAccident.setState("transferBase");
        if (!carAccident.isHelpReported()) {
            throw new RuntimeException("报案单未勾选基地代报案标识，无需转OA审核!!!");
        }

        try {
            carAccident.setAssistBaseID(carAccident.getCarEvaluations().getBase().getBranch().getId());
        } catch (Exception e) {
            throw new RuntimeException("转基地报案必须基地信息不能为空!!!");
        }
        carAccident = carAccidentRepository.saveAndFlush(carAccident);
        return  carAccident;
    }

    /**
     * 功能：基地代报案OA拒绝
     *
     */
    public CarAccident endOAAndRefuse(SimpleRequest request) {
        CarAccident carAccident = request.getO(CarAccident.class);
        carAccident.setState("store");
        carAccident.setHelpReported(false);
        carAccident = carAccidentRepository.saveAndFlush(carAccident);
        return  carAccident;
    }

    /**
     * 检查数据
     * @param request
     * @return
     */
    private void checkData(SimpleRequest request) {
        String id = request.get("id");
        int versions = request.get("version");  // 获取当前请求的版本信息
        CarAccident carAccident = carAccidentRepository.findOne(id);
        if (carAccident == null) throw new RuntimeException("车险报案单【" + id + "】在系统中不存在。");
        if (carAccident.getVersion() != versions) throw new RuntimeException("记录已更新或已删除，请重新提交！");
    }

    /**
     * 更新或插入会员扩展表
     * @param request
     * @return
     */
    private CarAccident updateOrInsertCustomerExpand(SimpleRequest request) {
        JSONObject param = request.getJO();
        CarAccident carAccident = request.getO(CarAccident.class);
        String carLicense= carAccident.getCarNumber();
        FnCustomerExpand customerExpand;
        if (Objects.nonNull(carAccident.getDept())) {
            customerExpand = getFnCustomerExpand(carAccident, carLicense);
        }else {
            List<PickUpCar> list = SpringManager.getBean(PickUpCarRepository.class)
                    .findAll(JpaDsl.toCriteriaByEq("licenseNumber",carAccident.getCarNumber(),"state","approve"));
            if (list.size() == 0) {
                customerExpand = null;
            }else {
                customerExpand = list.get(0).getFnCustomerExpand();
            }
        }
        handleCustomerExpand(carAccident, carLicense, customerExpand);

        return carAccident;
    }

    private void handleCustomerExpand(CarAccident carAccident, String carLicense, FnCustomerExpand customerExpand) {
        // 重新更新数据
        if (Objects.isNull(customerExpand)) {
            customerExpand = updateExpandData(carLicense,carAccident.getCompany(),null);
        }
        if (Objects.nonNull(customerExpand.getJekunModelCode())) {
            customerExpand.setCarModelService(SpringManager.getBean(FixedLossToForeign.class).getCarModelServiceLevel(customerExpand.getJekunModelCode()));
        }
        carAccident.setCustomerExpand(customerExpand);
        //如果扩展表得接车类型明细不为空则更新报案单
        List<PickUpTypeF> typeFList = customerExpand.getPickUpTypeF();
        if (typeFList.size() > 0){
            updateCarAccidentPickCarData(typeFList,carAccident);
        }
    }

    private FnCustomerExpand getFnCustomerExpand(CarAccident carAccident, String carLicense) {
        FnCustomerExpand customerExpand;//查询是否有有效得会员扩展表, 没有则新增
        List<FnCustomerExpand> customerExpands =  SpringManager.getBean(PickUpCarService.class)
                .findFnValidateCustomerExpandByDeptAndCarlicense(carAccident.getDept(),carLicense);
        if (customerExpands.size() >1){
            throw new RuntimeException("用户接车单存在多份,车牌:"+ carLicense);
        }
        customerExpand =customerExpands .stream().findFirst().orElse(null);
        if (customerExpand == null){
            customerExpand = SpringManager.getBean(ServicePlanceService.class)
                    .findValidServiceFnCustomerExpand(carAccident.getDept(),carLicense);
        }
        if (Objects.isNull(customerExpand)) {
            customerExpand = SpringManager.getBean(PickUpCarService.class)
                    .findCustomerExpandByCarAccident(carAccident.getDept(),carLicense);
        }
        return customerExpand;
    }

    /**
     * 更新车险报案单接车类型
     * @param
     * @return
     */
    public void updateCarAccidentPickCarData(List<PickUpTypeF> typeFList,CarAccident carAccident) {
        List<PickCarTypeAccident> list = typeFList.stream().map(
                pickUpType -> {
                    PickCarTypeAccident carTypeAccident = new PickCarTypeAccident();
                    carTypeAccident.setCarAccident(carAccident);
                    carTypeAccident.setPickUpType(pickUpType.getPickUpType());
                    carTypeAccident.setRemarks(pickUpType.getRemarks());
                    return carTypeAccident;
                }
        ).collect(Collectors.toList());
        carAccident.setTypeAccidents(list);
    }

    /**
     * 查询单个数据
     * @param request
     * @return
     */
    public CarAccident findOneWithID(SimpleRequest request) {
        String id = request.get("ID");

        CarAccident carAccident = carAccidentRepository.findOne(id);

        if (carAccident == null) throw new RuntimeException("车险报案：" + request.get("id") + " 在系统中不存在。");
        return carAccident;
    }
    /**
     * 查询保单信息(老框架取数)
     * @param request
     * @return
     */
    public JSONObject queryInsurance(SimpleRequest request) {
        JSONObject condition = new JSONObject();
        condition.put("CPHM", request.get("id"));
        JSONObject obj = SpringManager.getBean(PiManager.class).synErp("ipmBusinessAffairsService.queryInsurance", condition);
        return  JSONObject.parseObject(obj.get("obj").toString());

    }


    /**
     * 查询该车险报案单所有的相关信息
     * @param request
     * @return
     */
    public Map queryVehicleDamage(SimpleRequest request) {
        assert request.get("ID") != null;
        String id = request.get("ID");
        CarAccident carAccident = carAccidentRepository.findOne(id);
        if (carAccident == null) throw new RuntimeException("车险报案：" + request.get("id") + " 在系统中不存在。");
        Map map = MapUtil.mapped(carAccident);
        //查询定损报价单
        List<LossQuotationPlan> list = SpringManager.getBean(LossQuotationRepository.class).findPlanByCarAccident(id);
        assert map != null;
        if (list.size() >0) map.put("lossQuotations", list);
        List<LossQuotation> quotations = SpringManager.getBean(LossQuotationRepository.class).findByCarAccident(id);
        List<RetailOrder> orders = new ArrayList<>();
        if (quotations.size() >0) {
            quotations.forEach(
                    item -> {
                        List<RetailOrder> retailOrders = SpringManager.getBean(RetailOrderRepository.class).findAll(JpaDsl.toCriteriaByEq("source",item.getId()));
                        if (retailOrders.size() >0) orders.addAll(retailOrders);
                    }
            );
        }
        if (orders.size() >0 ) map.put("retailOrders", orders);
        return map;
    }







    /**
     * APP查询报案信息
     * @param request
     * @return
     */
    public Map queryInfoFromAPP(SimpleRequest request) {
        JSONObject data = request.getJO();
        String carLicense = data.getString("carLicense");
        String reportNumber = data.getString("reportNumber");
        List<CarAccident> list = carAccidentRepository.findAll(
                JpaDsl.toCriteriaByEq("reportNumber",reportNumber,"carNumber",carLicense));
        if (list.size() == 0) throw new RuntimeException("此车牌和报案号在系统不存在对应数据!!!");
        if (list.size() != 1) throw new RuntimeException("此车牌和报案号在系统存在多条数据!!!");
        CarAccident carAccident = list.stream().findFirst().orElseThrow(() ->new RuntimeException("获取数据失败"));
        return  MapUtil.mapper("reportNumber",carAccident.getReportNumber(),
                "carLicense",carAccident.getCarNumber(),
                "dept",carAccident.getDept().getName(),
                "insuranceCompany",carAccident.getInsuranceCompany().getName(),
                "state",carAccident.getState(),
                "caseType",carAccident.getCaseType().getDescription());
    }

    /**
     * 功能：转定损工单
     *
     * @param request
     * @return
     */
    public CarAccident claimWorkOrder(SimpleRequest request) {
        checkData(request);
        CarAccident carAccident = request.getO(CarAccident.class);
        if (Objects.isNull(carAccident.getDept())) {
            throw new RuntimeException("转定损工单,门店不能为空!!!");
        }
        List<ClaimWorkOrder> list = SpringManager.getBean(ClaimWorkOrderRepository.class).findAll(
                JpaDsl.toCriteriaByEq("sourceFrom", carAccident.getId())
        ).stream().filter(
                item -> {
                    String state = item.getState();
                    return !(Objects.equals("finish", state) || Objects.equals("repeal", state));
                }
        ).collect(Collectors.toList());
        if (list.size() > 0) {
            throw new RuntimeException("该车险报案单已存在未完成定损工单,请勿重复发起!!!");
        }
        long count = SpringManager.getBean(ClaimWorkOrderRepository.class).findAll(
                JpaDsl.toCriteriaByEq("reportNumber", carAccident.getReportNumber(), "carLicense", carAccident.getCarNumber())
        ).stream().filter(claimWorkOrder -> !claimWorkOrder.getState().equals("repeal")).count();
        if (count>0)return carAccident;

        Dept dept = carAccident.getDept();
        ClaimWorkOrder workOrder = new ClaimWorkOrder();
        workOrder.setSourceFrom(carAccident.getId());
        workOrder.setSourceFromName("车险报案单");
        workOrder.setDept(dept);
        workOrder.setWorkOrderType("A");
        workOrder.setInsuranceCompany(carAccident.getInsuranceCompany());
        workOrder.setCarLicense(carAccident.getCarNumber());
        workOrder.setReportNumber(carAccident.getReportNumber());
        PartyRole businessStaff = carAccident.getBusinessStaff();
        PartyRole staff = carAccident.getStaff();
        if (Objects.isNull(staff) || Objects.isNull(businessStaff)){
            throw new RuntimeException("门店跟进人和商务跟进人转定损工单不能为空!!!");
        }
        workOrder.setBusinessStaff(businessStaff);
        workOrder.setBusinessStaffName(businessStaff.getName());
        workOrder.setStoreStaff(staff);
        workOrder.setStoreStaffName(staff.getName());
        workOrder.setReportPerson(carAccident.getReportPerson());
        workOrder.setCarAccidentDate(carAccident.getCarAccidentDate());
        workOrder.setCarAccidentPlace(carAccident.getCarAccidentPlace());
        workOrder.setPhoneNumber(carAccident.getPhoneNumber());
        workOrder.setVersion(0);
        String remark = "车险报案转工单";
        workOrder = SpringManager.getBean(ClaimWorkOrderService.class).insertOperationRecord(request,workOrder,"新增",remark);
        invoke("fn.claimWorkOrder.save", MapUtil.mapped(workOrder));
        return  carAccident;
    }


    private void checkStoreQuota (CarAccident carAccident) {

        // List<Map> list = carAccidentRepository.findStoreQuota(carAccident.getDept().getId());
        // if (list.size() != 1) {
        //     throw new RuntimeException("系统中该门店得定损额度数据有误,联系后台人员处理!!!");
        // }
        // double quota = Double.parseDouble(list.get(0).get("SURPLUS_QUOTA").toString());
        // if (quota <= 1000 ) {
        //     throw new RuntimeException("门店定损额度不足一千,请及时销售保险补充额度!!!");
        // }
        if (Objects.nonNull(carAccident.getDept())) {
            CarEvaluation carEvaluation = carAccident.getCarEvaluations();
            if (Objects.nonNull(carEvaluation.getFixedLossType())){
                if  (Objects.equals("转基地定损",carEvaluation.getFixedLossType().getName())
                        && Objects.equals("本店维修",carEvaluation.getRepairPlace().getName())) {
                    SpringManager.getBean(LossQuotationService.class).checkInsuranceRule(carAccident.getInsuranceCompany(),carEvaluation.getBase().getCompany());
                    JSONObject object = getReimbursementRatio(carAccident.getDept().getCompany());
                    if (!Objects.isNull(object.getString("sys_break")) && Objects.equals("1",object.getString("sys_break"))) {
                        throw new RuntimeException("门店未签署委托定损协议,不能选择委托定损,请选择转基地定损,转基地维修!!!");
                    }
                }
            }
        }
    }

    /**
     * 获取补还比率
     * @param
     * @return
     */
    public JSONObject getReimbursementRatio (PartyRole company) {
        Map map = MapUtil.mapper(
                "COMPANY_ID", company.getId(), "OPERATION", company.getParty().getCorporate().getOperation().getId(),
                        "SYS_RQ",new Date(),"conditionStrategyId", "DS02"
                );
        Object obj = null;
        try {
            obj = invoke("condition.execConditionStrategy", map);
        } catch (Exception e) {
            throw new RuntimeException("取补还定损管理费率策略出错,请联系后台人员处理!!!公司id:"+company.getId());
        }
        return new JSONObject(Objects.requireNonNull(MapUtil.mapped(obj)));
    }

    /**
     * 更新会员扩展表信息
     * @param carLicense
     * @param company
     * @return
     */
    public FnCustomerExpand updateExpandData (String carLicense,PartyRole company,FnCustomerExpand expand) {
        String lockId = "findFnCustomerExpandAndSave_" + company.getId() + "_" + carLicense;
        int totalTime = 0;
        try {
            while (!distributedLock.lock(lockId,1000*60)){
                if (totalTime>1000*20)throw new RuntimeException("锁资源正在使用中:"+lockId);
                totalTime+=300;
                Thread.sleep(300);
            }
            JSONObject request = new JSONObject();
            request.put("carLicense", carLicense);
            request.put("vendorCode", company.queryAccessProvider().getId());
            Object obj = this.invoke("fn.customerCar.findOne", request);
            JSONObject resultJson = JSONObject.parseObject(obj.toString());
            //调用会员扩展表的通用更新插入方法返回数据
            expand = this.invoke("fn.customerExpand.updateOrInsert", MapUtil.mapper(
                    "customerExpand", expand != null ? MapUtil.mapper("id", expand.getId()) : null,
                    "customer", resultJson.get("customer"),
                    "customerCar", resultJson
            ));
            if (StringUtils.isEmpty(expand.getCarLicense())) {
                expand.setCarLicense(carLicense);
            }
        } catch (Exception e) {
            throw new RuntimeException(e.getMessage());
        } finally {
            // 释放锁
            distributedLock.unlock(lockId);
        }
        return expand;

    }

    /**
     * 第三方创建报案单
     * @param request 请求参数
     * @return 车险报案单号
     */
    public String thirdPartyCreate (SimpleRequest request) {
        JSONObject param = request.getJO();
        CarAccident carAccident = carAccidentRepository.findAll(JpaDsl.toCriteriaByEq(
                "carNumber", param.getString("carNumber"), "reportNumber", param.getString("reportNumber")
        )).stream().findFirst().orElse(null);
        if (Objects.nonNull(carAccident)) {
            return carAccident.getId();
        }else {
            carAccident = new CarAccident();
        }
        //默认参数
        carAccident.setSourceFrom(param.getString("insuranceCompany"));
        carAccident.setCreator("00002256");
        carAccident.setCreateDate(new Date());
        carAccident.setCarNumber(param.getString("carNumber"));
        carAccident.setReportNumber(param.getString("reportNumber"));
        carAccident.setReportPerson(param.getString("reportPerson"));
        carAccident.setPhoneNumber(param.getString("phoneNumber"));
        carAccident.setInjured(param.getIntValue("injured"));
        carAccident.setDie(param.getIntValue("die"));
        carAccident.setCarAccidentPlace(param.getString("carAccidentPlace"));
        carAccident.setCarAccidentDescribe(param.getString("carAccidentDescribe"));


        carAccident.setRepealDate(param.getDate("reportDate"));
        carAccident.setCarAccidentDate(param.getDate("carAccidentDate"));
        packageEntity(carAccident,param);
        FnCustomerExpand customerExpand;
        List<PickUpCar> list = SpringManager.getBean(PickUpCarRepository.class)
                .findAll(JpaDsl.toCriteriaByEq("licenseNumber",carAccident.getCarNumber(),"state","approve"));
        if (list.size() == 0) {
            customerExpand = null;
        }else {
            customerExpand = list.get(0).getFnCustomerExpand();
        }
        handleCustomerExpand(carAccident,carAccident.getCarNumber(),customerExpand);
        carAccident = carAccidentRepository.saveAndFlush(carAccident);
//        carAccidentSaveToApp(getAppSaveParam(carAccident));
        SpringManager.getBean(ApesLoggerService.class).sendSynEvent("event:ir.logger.create", MapUtil.mapper(
                "businessType", carAccident.getInnerBusinessType(),
                "businessKey", carAccident.getInnerBusinessKey(),
                "operate","保险公司推送" ,
                "workPostName", null,
                "audit", null,
                "operator_id", 1));
        JSONObject object = new JSONObject();
        object.put("id", carAccident.getId());
//        SpringManager.getBean(OutboxSubscriberService.class).commonSendRequest("local:CarAccident.synOldSystem","Accident" + carAccident.getId(),object);
        return carAccident.getId();
    }

    private void packageEntity(CarAccident carAccident,JSONObject param){
        //转换数据的Map,判断字段是否为空
        final Map<String, String> code_field = new HashMap<String, String>() {
            {
                put("中国人保", "0001");
                put("中国人寿", "0004");
                put("accidentType", "true");
                put("dangerType", "true");
                put("vehicleDuty", "true");
            }
        };
        BusinessAttributeValueRepository attributeRepository  = SpringManager.getBean(BusinessAttributeValueRepository.class);
        carAccident.setInsuranceCompany(
                SpringManager.getBean(InsuranceCompanyRepository.class).findOne(code_field.get(param.getString("insuranceCompany")))
        );
        String[] strings = new String[3];
        strings[0] = "CarAccident";
        for (Map.Entry<String, Object> entry : param.entrySet()) {
            if (Objects.nonNull(code_field.get(entry.getKey()))) {
                strings[1] = entry.getKey();
                strings[2] = entry.getValue().toString();
                String field = String.join(".", strings);
                BusinessAttributeValue attribute = attributeRepository.findOne(field);
                //不同属性调用对应的setValue方法
                CarAccident.methodMap.get(entry.getKey()).accept(attribute);
            }
        }
        String caseType = "caseType";
        if (Objects.nonNull(param.getString(caseType))) {
            Enumeration enumeration = SpringManager.getBean(EnumerationRepository.class).findAll(
                    JpaDsl.toCriteriaByEq("type.id", caseType, "code", param.getString(caseType))
            ).stream().findFirst().orElse(null);
            carAccident.setCaseType(enumeration);
        }
        carAccident.setCompany(SpringManager.getBean(PartyRoleRepository.class).findOne("1001"));
    }

    private void checkDamagePoint(CarAccident carAccident){
        InsuranceCompany insuranceCompany = carAccident.getInsuranceCompany();
        if (!insuranceCompany.isCooperation())return;
        if (Objects.nonNull(carAccident.getCarEvaluations()) && Objects.nonNull(carAccident.getCarEvaluations().getFixedLossType())){
            CarEvaluation carEvaluation = carAccident.getCarEvaluations();
            Dept dept = carAccident.getDept();
            if (Objects.isNull(dept)) {
                throw new RuntimeException("门店不能为空!!!");
            }
            if(Objects.equals("B",carEvaluation.getFixedLossType().getCode())) dept = carAccident.getCarEvaluations().getBase();
            InsuranceRule rule = SpringManager.getBean(InsuranceRuleService.class).getRuleFromDept(dept, insuranceCompany);
            if (Objects.isNull(rule)) {
                //[广州车宝行凤凰店] 与 保险公司：[0001中国人民财产保险股份有限公司] 无有效定损规则，
                //请联系 [商务中心对接人]维护定损规则。
                throw new RuntimeException("["+dept.getName()+"] 与 保险公司：["+insuranceCompany.getId()+insuranceCompany.getName()+"] 无有效定损规则,请联系 [商务中心对接人]维护定损规则。");
            }
        }
    }
    private CarAccident repealMark(SimpleRequest request){
        JSONObject jo = request.getJO();
        System.out.println(jo);
        return null;

    }

    private JSONObject findLossDetails(SimpleRequest request){
        JSONObject jo = request.getJO();
        String key = jo.getString("key");
        JSONObject result = new JSONObject();
        //todo 待app提供接口
        Object returnInfo = "";
        Object payInfo = this.invoke("retail.order.queryCarAccidentPayInfo", jo);
        Object receivedInfo = this.invoke("fn.lossReceivedItem.queryCarAccidentReceivedInfo", jo);
        Object lossInfo = this.invoke("fn.lossQuotation.findLossInfo", jo);

        result.put("returnInfo",returnInfo);
        result.put("payInfo",payInfo);
        result.put("receivedInfo",receivedInfo);
        result.put("lossInfo",lossInfo);

        return result;

    }

    private String checkHistory15DayCarAccident(SimpleRequest request){
        JSONObject jo = request.getJO();
        String reportNumber = jo.getString("reportNumber");
        String carNumber = jo.getString("carNumber");
        String id = jo.getString("id");
        List<CarAccident> historyCarAccident = getCarAccidents(reportNumber, carNumber,id);
        if (historyCarAccident.isEmpty())return null;
        return historyCarAccident.get(0).getId();

    }

    private List<CarAccident> getCarAccidents(String reportNumber, String carNumber,String id) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(new Date());
        calendar.add(Calendar.DATE,-15);
        return carAccidentRepository.findAll(JpaDsl.toCriteria(
                "reportNumber", "EQ", reportNumber,
                "id", "NE", id,
                "carNumber", "EQ", carNumber,
                "createDate", "GT", calendar.getTime()));
    }

    private void checkReportNumberStandard(CarAccident carAccident) {
        if (Objects.isNull(carAccident.getReportNumber())) throw new RuntimeException("请填写报案号。");
        if (Objects.isNull(carAccident.getDept()) || Objects.isNull(carAccident.getInsuranceCompany())) return;
        InsuranceCompany insuranceCompany = carAccident.getInsuranceCompany();
        Store store = storeRepository.findAll(JpaDsl.toCriteriaByEq("dept.id", carAccident.getDept().getId())).stream().findFirst().orElse(null);
        if (Objects.isNull(store.getCity())) return;
        insuranceCompany.getInsuranceCompanyDetails().stream().forEach(item->{
            String reportNumberStandard = item.getReportNumberStandard();
            if (Objects.isNull(reportNumberStandard)) return;
            if (!Objects.isNull(item.getCity())
                    && item.getCity().getId().equals(store.getCity().getId())
                    && !carAccident.getReportNumber().startsWith(reportNumberStandard)){
                throw new RuntimeException("请填写开头为" + reportNumberStandard + "的报案号。");
            }
        });
    }
    private Object searchChangeCondition(SimpleRequest request){
        JSONObject jo = request.getJO();
        JSONArray condition = jo.getJSONArray("condition");
        JSONArray newCondition = new JSONArray();
        for (Object o : condition) {
            if (!(o instanceof JSONObject)){
                newCondition.add(o);
                continue;
            }
            JSONObject jsonObject = (JSONObject) o;
            switch (jsonObject.getString("field")) {
                case "terminal":
                    break;
                default:
                    newCondition.add(jsonObject);
            }
        }
        jo.put("condition",newCondition);
        return jo;
    }
}
